package com.liujianlei.forum_system.controller;

import com.liujianlei.forum_system.common.AppResult;
import com.liujianlei.forum_system.common.ResultCode;
import com.liujianlei.forum_system.config.AppConfig;
import com.liujianlei.forum_system.exception.ApplicationException;
import com.liujianlei.forum_system.model.User;
import com.liujianlei.forum_system.service.IUserService;
import com.liujianlei.forum_system.utils.MD5Utils;
import com.liujianlei.forum_system.utils.StringUtils;
import com.liujianlei.forum_system.utils.UUIDUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @author tongchen
 * @create 2023-05-21 15:57
 */
@Slf4j
@RestController
@RequestMapping("/user")
@Api(tags = "用户接口")
public class UserController {
@Resource
private IUserService userService;
@PostMapping("/register")
@ApiOperation("注册新用户（普通）的方法")
    public AppResult register(@RequestParam("username")@NonNull @ApiParam(value = "用户名") String username, @RequestParam("nickname")@NonNull @ApiParam(value = "昵称") String nickname, @RequestParam(value = "gender",required = false)
     @ApiParam(value = "性别") Byte gender , @RequestParam("password")@NonNull @ApiParam(value = "密码")  String password, @RequestParam("passwordRepeat") @NonNull @ApiParam(value = "确认密码")  String passwordRepeat){
        //测试数据的有效性
        if(gender==null||gender<0||gender>2){
            //如果错误，我们将性别信息进行清空
            gender=2;
        }
        //判断密码和确认密码是否相同
        if(!password.equals(passwordRepeat)){
            log.error(ResultCode.FAILED_TWO_PWD_NOT_SAME.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME));
        }
        //对密码进行加密
        String salt = UUIDUtils.UUID_32();
        String newPassword = MD5Utils.md5Salt(password, salt);
        //将所有字段信息储存
        User user = new User();
        user.setUsername(username);
        user.setNickname(nickname);
        user.setGender(gender);
        user.setPassword(newPassword);
        user.setSalt(salt);
    userService.createCommonUser(user);
        return AppResult.success("用户新增成功!");
    }
    @ApiOperation("登录方法")
    @PostMapping("/login")
    public AppResult login(HttpServletRequest request, @ApiParam(value = "用户名") @RequestParam(value = "username")@NonNull String username, @ApiParam(value = "密码")@RequestParam(value = "password")@NonNull String password){
        //调用service登录方法
        User loginUser = userService.login(username, password);
        //存储session
        HttpSession session=request.getSession(true);
        session.setAttribute(AppConfig.USER_SESSION, loginUser);
        //返回结果
        return AppResult.success("登录成功",loginUser);
    }
    @ApiOperation("用户退出方法")
    @GetMapping("/logout")
    public AppResult logout(HttpServletRequest request){
        //检查session是否有效
        HttpSession session = request.getSession(false);
        if(session==null){
            //记录错误日志
            log.error(ResultCode.USER_NOT_LOG.toString());
            //返回错误信息
            throw new ApplicationException(AppResult.failed(ResultCode.USER_NOT_LOG));
        }
        //去除session
        Object user = session.getAttribute(AppConfig.USER_SESSION);
        log.info("用户退出"+user);
        session.invalidate();
        //返回结果
        return AppResult.success("用户退出成功.");
    }
    @GetMapping("/info")
    @ApiOperation("展示用户信息的方法")
    public AppResult userInfo(HttpServletRequest request ,@ApiParam(value = "用户id")@RequestParam(value = "id" ,required = false) Long id){
        //判断是否存在id
        //不存在id返回当前登录的用户信息
        if(id==null){
            //获取session
            HttpSession session = request.getSession(false);
            //session为null说明用户未登录
            if(session==null){
                //记录错误日志
                log.error(ResultCode.USER_NOT_LOG.toString());
                //返回错误信息
                throw new ApplicationException(AppResult.failed(ResultCode.USER_NOT_LOG));
            }
            User user = (User)session.getAttribute(AppConfig.USER_SESSION);
            if(user==null){
                //记录错误日志
                log.error(ResultCode.USER_NOT_LOG.toString());
                //返回错误信息
                throw new ApplicationException(AppResult.failed(ResultCode.USER_NOT_LOG));
            }
            return AppResult.success("用户查询成功！",user);
        }
        //存在id返回指定id的用户
        else{
            User user = userService.selectByPrimaryKey(id);
            if(user==null){
                log.error(ResultCode.FAILED_USER_NOT_EXISTS.toString());
                throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
            }
            return AppResult.success("用户查询成功",user);
        }

    }
    @ApiOperation("修改用户个人信息的方法!")
    @PostMapping("/modifyInfo")
    public AppResult modifyInfo (HttpServletRequest request,
                                 @ApiParam("用户Id") @RequestParam("id") @NonNull Long id,
                                 @ApiParam("性别") @RequestParam(value = "gender", required = false) Byte gender,
                                 @ApiParam("昵称") @RequestParam(value = "nickname", required = false) String nickname,
                                 @ApiParam("电话号码") @RequestParam(value = "phoneNum", required = false) String phoneNum,
                                 @ApiParam("邮箱") @RequestParam(value = "email", required = false) String email,
                                 @ApiParam("个人简介") @RequestParam(value = "remark", required = false) String remark) {
        // 校验
        if (gender == null
                && StringUtils.isEmpty(nickname)
                && StringUtils.isEmpty(phoneNum)
                && StringUtils.isEmpty(email)
                && StringUtils.isEmpty(remark)) {
            // 参数同时为空时返回错误信息
            return AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE.toString());
        }
        // 校验传入的Id是否为当前登录用户
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);
        if (user.getId() != id) {
            // 返回错误
            return AppResult.failed(ResultCode.FAILED_UNAUTHORIZED.toString());
        }
        // 调用service
        userService.modifyInfo(id, gender, nickname, phoneNum, email, remark);
        // 重新获取用户信息，更新session
        user = userService.selectByPrimaryKey(id);
        session.setAttribute(AppConfig.USER_SESSION, user);
        // 返回结果
        return AppResult.success();
    }

@ApiOperation("修改密码的方法")
@PostMapping("/modifyPwd")
  public AppResult modifyPassword(HttpServletRequest request,@NonNull@RequestParam(value = "id")@ApiParam(value = "用户id") Long id,@NonNull@RequestParam("oldPassword")@ApiParam(value = "用户的旧密码") String oldPassword,@NonNull@RequestParam("newPassword")@ApiParam(value = "新密码") String newPassword,@NonNull @RequestParam("passwordRepeat")@ApiParam(value = "重复密码") String passwordRepeat){
    //判断当前用户是否登录，没有登录直接报错
      HttpSession session = request.getSession(false);
      if(session==null){
          log.error(ResultCode.USER_NOT_LOG.toString());
          throw new ApplicationException(AppResult.failed(ResultCode.USER_NOT_LOG));
      }
      User loginUser =(User) session.getAttribute(AppConfig.USER_SESSION);
      if(loginUser==null){
          log.error(ResultCode.USER_NOT_LOG.toString());
          throw new ApplicationException(AppResult.failed(ResultCode.USER_NOT_LOG));
      }
      //登录之后判断当前用户是否有权修改密码
      //无权直接报错
      if(loginUser.getId()!=id){
          log.error(ResultCode.FAILED_UNAUTHORIZED.toString());
          throw new ApplicationException(AppResult.failed(ResultCode.FAILED_UNAUTHORIZED));
      }
      //判断两次密码是否一致
      if(!newPassword.equals(passwordRepeat)){
          //密码不一致进行报错
          log.error(ResultCode.FAILED_TWO_PWD_NOT_SAME.toString());
          throw new ApplicationException(AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME));
      }
      //密码一致则进行修改信息
      userService.modifyPassword(id, oldPassword, newPassword, passwordRepeat);
      log.info("密码修改成功,"+loginUser.getUsername());
      return AppResult.success("密码修改成功");
  }

}
